﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core.EntryType;
using COFE.Core;
using System.Xml.Linq;
using COFE.Web;

namespace COFE.Web
{
    /// <summary>
    /// Represents an EntryBaseType, which is a type information of a specified type of entry.
    /// </summary>
    public class EntryType : SupportLink, ISupportXml, ISupportLinkTemplates
    {
        #region Constructor

        public EntryType(IEntryTypeInfo entryTypeInfo)
        {
            ID = entryTypeInfo.ID;
            _contentType = entryTypeInfo.MIMEType;
            _description = entryTypeInfo.Description;            
        }

        private EntryType(Guid id, string contentType, string description)
        {
            ID = id;
            _contentType = contentType;
            _description = description;            
        }

        #endregion

        #region Methods
     
        /// <summary>
        /// Return a list of LinkTemplate s, LinkTemplates are look like "/#contents#/#id#".
        /// </summary>
        /// <returns></returns>
        public IEnumerable<LinkTemplate> GetLinkTemplates()
        {
            yield return new LinkTemplate(MediaType.Png, RelationType.Icon, ServiceConstants.Templates.EntryTypeIcon);
        }

        public Dictionary<string, string> GetLinkParameterDic()
        {
            return new Dictionary<string, string>()
            {
                { "#id#", ID.ToString() }
            };
        }

        public override IEnumerable<Link> GetLinks()
        {
            return this.CreateLinks();
        }

        public override string ToString()
        {
            return Description;
        }

        /// <summary>
        /// Serialize an entry type.
        /// </summary>
        /// <returns></returns>
        public XElement ToXml(bool indentLinks = false)
        {
            var entryXml = new XElement(XNames.EntryType,
                                 new XAttribute(XNames.ID, this.ID.ToString("n"))
                                 );

            if (!(String.IsNullOrEmpty(this.ContentType)))
                entryXml.Add(new XAttribute(XNames.MediaType, this.ContentType));
            entryXml.Add(new XAttribute(XNames.Description, this.Description));

            writeLinks(entryXml, indentLinks);
            return entryXml;
        }

        /// <summary>
        /// Deserialize an Entry, 
        /// Metadata cannot be deserialized.
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="itemXml"></param>
        /// <param name="canConstruct"></param>
        /// <returns></returns>
        public static EntryType FromXml(IUserProfile profile, XElement itemXml, bool canConstruct)
        {
            string description = itemXml.Attribute(XNames.Description).Value;
            string contentType = itemXml.Element(XNames.MediaType) != null ? itemXml.Element(XNames.MediaType).Value : null;

            List<Link> links = new List<Link>();
            foreach (var xEle in itemXml.Elements(XNames.Link))
                links.Add(Link.FromXml(xEle));

            Guid id = new Guid(itemXml.Attribute(XNames.ID).Value);

            return new EntryType(id, contentType, description);
        }


        #endregion

        #region Data
        
        private string _contentType, _description;
        private Guid _id = Guid.Empty;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets id of an entry, using COFEEntry's GetHashGuid() method.
        /// </summary>
        public Guid ID { get { return _id; } set { _id = value; } }

        /// <summary>
        /// MIMEContentType if available, e.g. text/plain-text
        /// </summary>
        public string ContentType { get { return _contentType; } set { } }

        /// <summary>
        /// Description of the EntryBaseType, e.g. Zip archive.
        /// </summary>
        public string Description { get { return _description; } set { } }


        #endregion


        
    }
}
